﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MvcEngine.Blog.Models.Entities;
using MvcEngine.Core.Utils;
using MvcEngine.Blog.Repositories;
using MvcEngine.Core;
using MvcEngine.Core.Pagination;
using MvcEngine.Core.Helpers;
using MvcEngine.Core.Repositories;

namespace MvcEngine.Blog.Managers
{
    public class BlogCategoryManager : IBlogCategoryManager
    {
        private readonly IBlogCategoryRepository categoryRepository = null;

        public BlogCategoryManager(IBlogCategoryRepository categoryRepository)
        {
            this.categoryRepository = categoryRepository;
        }

        public static IBlogCategoryManager Current
        {
            get { return IoC.Resolve<IBlogCategoryManager>(); }
        }

        public IList<BlogCategory> GetAll(Guid blogId)
        {
            return CacheManager.Current.FromCache(string.Format(BlogCacheKeys.CategoryKeys.BlogCategories, blogId), BlogCacheKeys.CategoryKeys.Category,
                () => categoryRepository.GetAll(blogId));
        }

        public IPagination<BlogCategory> Get(Guid blogId, int pageNumber, int pageSize)
        {
            return CacheManager.Current.FromCache(string.Format(BlogCacheKeys.CategoryKeys.Paging, blogId, pageNumber, pageSize), BlogCacheKeys.CategoryKeys.Category,
                () => categoryRepository.GetAll(blogId, pageNumber, pageSize));
        }

        public BlogCategory Get(Guid categoryId)
        {
            return CacheManager.Current.FromCache(string.Format(BlogCacheKeys.CategoryKeys.CategoryId, categoryId), BlogCacheKeys.CategoryKeys.Category,
                () => categoryRepository.Get(categoryId));
        }

        public IList<BlogCategory> GetAllByPost(Guid postId)
        {
            return CacheManager.Current.FromCache(string.Format(BlogCacheKeys.CategoryKeys.PostCategories, postId), BlogCacheKeys.CategoryKeys.Category,
                () => categoryRepository.GetAllByPost(postId));
        }

        public void Save(BlogCategory category)
        {
            Guard.ThrowIfEmptyGuid(category.BlogId);
            bool isUpdated = true;
            using (var unitOfWork = UnitOfWorkHelper.Get())
            {
                BlogCategory categoryToSave = null;
                if (category.Id != Guid.Empty)
                {
                    categoryToSave = categoryRepository.Get(category.Id);
                }

                if (categoryToSave == null)
                {
                    categoryToSave = new BlogCategory { Id = Guid.NewGuid() };
                    categoryToSave.CreatedDate = DateTime.Now;
                    isUpdated = false;
                }

                categoryToSave.ModifiedDate = DateTime.Now;
                categoryToSave.Name = category.Name;
                categoryToSave.Slug = category.Slug;
                categoryToSave.BlogId = category.BlogId;

                if (isUpdated)
                {
                    categoryRepository.Update(categoryToSave);
                }
                else 
                {
                    categoryRepository.Add(categoryToSave);
                }
                unitOfWork.Commit();
            }
            CacheManager.Current.ClearCache(BlogCacheKeys.CategoryKeys.Category);
        }

        public void Delete(Guid categoryId)
        {
            categoryRepository.Delete(categoryId);
            CacheManager.Current.ClearCache(BlogCacheKeys.CategoryKeys.Category);
        }
    }
}
